package cayte.sudoku.crack;

import android.graphics.Color;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import cayte.sudoku.crack.MainActivity.State;
import cayte.sudoku.crack.comm.CrackUtil;
import cayte.sudoku.crack.comm.IsNull;
import cayte.sudoku.crack.obj.Gr;
import cayte.sudoku.crack.obj.Sudoku;

public class TableView {
	private TextView[][] table;
	private int gridMeasurement = 0;
	private TextView select = null;
	private boolean isClick = true;
	private CrackUtil util;
	private MainActivity con;

	public TableView(MainActivity context) {
		// TODO Auto-generated constructor stub
		con = context;
		table = new TextView[][] {
				{ null, null, null, null, null, null, null, null, null },
				{ null, null, null, null, null, null, null, null, null },
				{ null, null, null, null, null, null, null, null, null },
				{ null, null, null, null, null, null, null, null, null },
				{ null, null, null, null, null, null, null, null, null },
				{ null, null, null, null, null, null, null, null, null },
				{ null, null, null, null, null, null, null, null, null },
				{ null, null, null, null, null, null, null, null, null },
				{ null, null, null, null, null, null, null, null, null } };
		util = new CrackUtil(this);
	}

	public void init(View view) {
		// TODO Auto-generated method stub
		// find view
		View row1 = view.findViewById(R.id.r_1);
		initRow(0, row1);
		View row2 = view.findViewById(R.id.r_2);
		initRow(1, row2);
		View row3 = view.findViewById(R.id.r_3);
		initRow(2, row3);
		View row4 = view.findViewById(R.id.r_4);
		initRow(3, row4);
		View row5 = view.findViewById(R.id.r_5);
		initRow(4, row5);
		View row6 = view.findViewById(R.id.r_6);
		initRow(5, row6);
		View row7 = view.findViewById(R.id.r_7);
		initRow(6, row7);
		View row8 = view.findViewById(R.id.r_8);
		initRow(7, row8);
		View row9 = view.findViewById(R.id.r_9);
		initRow(8, row9);
		// get gridMeasurement
		gridMeasurement = (SystemParams.SCREEN_WIDTH
				- (view.getPaddingLeft() * 3) - ((View) view.getParent())
				.getPaddingLeft() * 2) / 9;
		// init grids
		initGrid();
	}

	public int getGridMeasurement() {
		return gridMeasurement;
	}

	private void initRow(int rowIndex, View rowView) {
		// TODO Auto-generated method stub
		table[rowIndex][0] = (TextView) rowView.findViewById(R.id.c_1);
		table[rowIndex][0].setTag(rowIndex + "," + 0);
		table[rowIndex][1] = (TextView) rowView.findViewById(R.id.c_2);
		table[rowIndex][1].setTag(rowIndex + "," + 1);
		table[rowIndex][2] = (TextView) rowView.findViewById(R.id.c_3);
		table[rowIndex][2].setTag(rowIndex + "," + 2);
		table[rowIndex][3] = (TextView) rowView.findViewById(R.id.c_4);
		table[rowIndex][3].setTag(rowIndex + "," + 3);
		table[rowIndex][4] = (TextView) rowView.findViewById(R.id.c_5);
		table[rowIndex][4].setTag(rowIndex + "," + 4);
		table[rowIndex][5] = (TextView) rowView.findViewById(R.id.c_6);
		table[rowIndex][5].setTag(rowIndex + "," + 5);
		table[rowIndex][6] = (TextView) rowView.findViewById(R.id.c_7);
		table[rowIndex][6].setTag(rowIndex + "," + 6);
		table[rowIndex][7] = (TextView) rowView.findViewById(R.id.c_8);
		table[rowIndex][7].setTag(rowIndex + "," + 7);
		table[rowIndex][8] = (TextView) rowView.findViewById(R.id.c_9);
		table[rowIndex][8].setTag(rowIndex + "," + 8);
	}

	private void initGrid() {
		// TODO Auto-generated method stub
		LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
				gridMeasurement, gridMeasurement);
		GridListener listener = new GridListener();
		for (int r = 0; r < table.length; r++) {
			for (int c = 0; c < table[r].length; c++) {
				// init one grid
				table[r][c].setLayoutParams(lp);
				table[r][c].setOnClickListener(listener);
			}
		}
	}

	private class GridListener implements View.OnClickListener {

		@Override
		public void onClick(View v) {
			if (isClick)
				setSelect(v);
		}
	}

	public void setClick(boolean isClick) {
		this.isClick = isClick;
	}

	public void setSelect(View v) {
		if (select != null && select.equals(v)) {
			setSelect(null);
			return;
		}
		if (select != null)
			select.setBackgroundResource(R.drawable.box_grid);
		select = (TextView) v;
		if (select != null)
			select.setBackgroundResource(R.drawable.box_grid_select);
	}

	public void next() {
		if (select == null)
			return;
		int row = Integer.parseInt(select.getTag().toString().split(",")[0]);
		int col = Integer.parseInt(select.getTag().toString().split(",")[1]);
		col++;
		if (col == 9) {
			row++;
			col = 0;
			if (row == 9)
				row = 0;
		}
		setSelect(table[row][col]);
	}

	public void setValue(final String value) {
		// TODO Auto-generated method stub
		if (select == null)
			return;
		select.setTextColor(Color.BLACK);
		select.setText(value);
	}

	public void setValue(TextView tv, Gr g) {
		// TODO Auto-generated method stub
		if (tv == null || g == null)
			return;
		if (g.isValueNull()) {
			tv.setTextColor(Color.BLACK);
			tv.setText("");
			return;
		}
		if (g.getValue() < 1 || g.getValue() > 9)
			return;
		if (g.isCrack())
			tv.setTextColor(Color.BLUE);
		else
			tv.setTextColor(Color.BLACK);
		tv.setText(g.getValue() + "");

	}

	public void setValue(final int r, final int c, final Gr g) {
		// TODO Auto-generated method stub
		con.runOnUiThread(new Runnable() {

			@Override
			public void run() {
				// TODO Auto-generated method stub
				setValue(table[r][c], g);
			}
		});
	}

	public void remove() {
		// TODO Auto-generated method stub
		if (select == null)
			return;
		con.runOnUiThread(new Runnable() {

			@Override
			public void run() {
				// TODO Auto-generated method stub
				select.setText(R.string._null);
			}
		});
	}

	public void clear() {
		// TODO Auto-generated method stub
		setSelect(null);
		con.runOnUiThread(new Runnable() {

			@Override
			public void run() {
				// TODO Auto-generated method stub
				for (int r = 0; r < table.length; r++) {
					for (int c = 0; c < table[r].length; c++) {
						table[r][c].setText(R.string._null);
					}
				}
			}
		});
	}

	private Sudoku sudoku = null;

	public void reset() {
		// TODO Auto-generated method stub
		if (sudoku == null)
			return;
		for (int r = 0; r < sudoku.grs.length; r++) {
			for (int c = 0; c < sudoku.grs[r].length; c++) {
				if (sudoku.grs[r][c].isCrack())
					sudoku.grs[r][c] = new Gr();
			}
		}
		updateTableView(sudoku);
	}

	public void crack() {
		// TODO Auto-generated method stub
		sudoku = new Sudoku();
		Gr g = null;
		for (int r = 0; r < table.length; r++) {
			for (int c = 0; c < table[r].length; c++) {
				if (IsNull.check(table[r][c].getText()))
					g = new Gr();
				else
					g = new Gr(Integer.parseInt(table[r][c].getText()
							.toString()), false);
				sudoku.setGr(r, c, g);
			}
		}
		util.setRootSudoku(new Sudoku(sudoku));
		util.crack();
	}

	public void stop() {
		// TODO Auto-generated method stub
		util.stop();
	}

	public void updateTableView(final Sudoku sudoku) {
		if (sudoku == null)
			return;

		con.runOnUiThread(new Runnable() {

			@Override
			public void run() {
				// TODO Auto-generated method stub
				Gr g = null;
				for (int r = 0; r < table.length; r++) {
					for (int c = 0; c < table[r].length; c++) {
						g = sudoku.getGr(r, c);
						setValue(table[r][c], g);
					}
				}
			}
		});
	}

	public void showEnd(State state) {
		// TODO Auto-generated method stub
		switch (state) {
		case END:
			show(R.string.crackError);
			con.doCrack(State.END);
			break;
		case RESET:
			show(R.string.rootError);
			con.doCrack(State.END);
			break;
		case SUCCESS:
			show(R.string.crackSuccess);
			con.doCrack(State.END);
			break;
		default:
			break;
		}

	}

	public void show(int resId) {
		// TODO Auto-generated method stub
		show(con.getString(resId));
	}

	public void show(final String content) {
		// TODO Auto-generated method stub
		con.runOnUiThread(new Runnable() {

			@Override
			public void run() {
				// TODO Auto-generated method stub
				Toast.makeText(con, content, Toast.LENGTH_SHORT).show();
			}
		});
	}

	public void testData() {
		Sudoku sudoku = new Sudoku();
		sudoku.setTestData(0, "900000060");
		sudoku.setTestData(1, "305008000");
		sudoku.setTestData(2, "000603700");
		sudoku.setTestData(3, "084030000");
		sudoku.setTestData(4, "100000009");
		sudoku.setTestData(5, "000060310");
		sudoku.setTestData(6, "002805000");
		sudoku.setTestData(7, "000400201");
		sudoku.setTestData(8, "050000006");
		updateTableView(sudoku);
	}
}
